package com.yuns.config;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @description: TODO: websocket
 * @author: zhansang
 * @create: 2020-11-17 19:27
 * @version: 1.0
 **/
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebsocketServer  {

    /**
     * 日志
     */
    private  static  final Logger logger = LoggerFactory.getLogger(WebsocketServer.class);

    /**
     * 静态变量，用来计算当前在线连接数
     */
    private static Integer onlineCount = 0;


    /**
     * concurrent包的线程安全set,用来存放每个客户端对应的MyWebsocket对象
     */
    private static ConcurrentHashMap<String,WebsocketServer> webSocketMap = new ConcurrentHashMap();

    /**
     * 与某个客户端连接绘画，需要通过它发送数据给客户端
     */
    private Session session;

    /**
     * 接受userId
     */
    private String userId = "";

    /**
     * 链接成功调用的方法
     * @param session 会话信息
     * @param userId 用户id
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId")String userId ){
        this.session = session;
        this.userId = userId;
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            webSocketMap.put(userId,this);
            // 加入到set中
        } else {
            webSocketMap.put(userId,this);
            // 加入到set中
            addOnlineCount();
        }

        logger.info("用户："+userId+"连接，当前在线人数："+getOnlineCount());

        try {

        }catch (Exception ex){
            logger.info("用户："+userId+"，网络异常！");
        }

    }


    /**
     * 关闭时候触发的方法
     */
    @OnClose
    public void onClose(){
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            // 从set中移除
            subOnlineCount();
        }
        logger.info("用户："+userId+"，退出，当前在线人数："+getOnlineCount());
    }

    /**
     * 收到客户端消息调用的对象
     * @param message 消息信息 JSON数据
     * @param session 对话
     */
    @OnMessage
    public void onMessage(String message,Session session){
        logger.info("用户："+userId+"，消息："+message);
        if(StringUtils.isNotBlank(message)){
            // 解析发的报文
            logger.info(message);
        }
    }

    /**
     * 发生错误触发的方法
     * @param session 对话
     * @param throwable 异常对象
     */
    @OnError
    public void onError(Session session,Throwable throwable){
        logger.info("用户:"+userId+"，发生错误。错误原因："+throwable.getMessage());

        throwable.printStackTrace();
    }


    /**
     * 发送消息的方法
     * @param message 消息
     * @throws IOException 异常对象
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 发送自定义消息
     */
    public static void sendInfo(String message,@PathParam("userId")String userId)throws IOException{
        logger.info("发送消息到："+userId+"，消息内容："+message);
        if(StringUtils.isNotBlank(message) && webSocketMap.containsKey(userId)){
            webSocketMap.get(userId).sendMessage(message);
        }else{
            logger.error("用户："+userId+"，不在线！");
        }
    }

    public static synchronized  Integer getOnlineCount(){
        return WebsocketServer.onlineCount;
    }

    public static synchronized  void addOnlineCount(){
        WebsocketServer.onlineCount ++;
    }

    public static synchronized  void subOnlineCount(){
        WebsocketServer.onlineCount --;
    }

}
